package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumAttributeValueService;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.cache.TsCache;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.util.BeanUtil;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

	@Autowired
	private AlbumInfoMapper albumInfoMapper;
    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;
    @Autowired
    private AlbumStatMapper albumStatMapper;
    @Resource
    private AlbumAttributeValueService albumAttributeValueService;
    @Resource
    private RabbitService rabbitService;

    @Resource
    private RedissonClient redissonClient;
    /**
     * 根据专辑ID，查询统计信息
     * @param albumId
     * @return
     */
    @Override
    @TsCache(prefix = "statVo:")
    public AlbumStatVo getAlbumStat(Long albumId) {
        return albumInfoMapper.selectAlbumStat(albumId);
    }

    /**
     * 根据用户ID，获取全部专辑信息
     * @param userId
     * @return
     */
    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        Page<AlbumInfo> albumInfoPage = new Page<>(1, 10);
        //select id, album_title from album_info where user_id = 1 order by id desc
        //调用service层分页
        page(albumInfoPage,
                new LambdaQueryWrapper<AlbumInfo>().
                        eq(AlbumInfo::getUserId, userId).
                        select(AlbumInfo::getId, AlbumInfo::getAlbumTitle).
                        orderByDesc(AlbumInfo::getId));
        //获取结果集
        List<AlbumInfo> records = albumInfoPage.getRecords();

        return records;
    }

    /**
     * 根据专辑ID,更新专辑信息
     * @param albumId
     * @param albumInfoVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
        //1.更新专辑表
        AlbumInfo albumInfo = getById(albumId);
        BeanUtils.copyProperties(albumInfoVo,albumInfo);
        albumInfoMapper.updateById(albumInfo);

        //2.删除专辑属性值中间表数据
        //update from album_attribute_value set is_delete=1 where album_id = ? and is_delete=0;
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));

        //3.插入属性值中间表
        List<AlbumAttributeValue> albumAttributeValueList = albumInfoVo.getAlbumAttributeValueVoList().stream().map(albumAttributeValueVo -> {
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
            albumAttributeValue.setAlbumId(albumId);
            return albumAttributeValue;
        }).collect(Collectors.toList());
        //批量插入
        //insert into album_attribute_value values (?,?,?),(?,?,?),(?,?,?);mybatis-plus 的批量插入！
        albumAttributeValueService.saveBatch(albumAttributeValueList);

        if ("1".equals(albumInfo.getIsOpen())){
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId());
            //	将新增的商品SKUID存入布隆过滤器
            //	获取布隆过滤器，将新增skuID存入布隆过滤器
            RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
            bloomFilter.add(albumInfo.getId());
        }else{
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_LOWER,albumInfo.getId());
        }
    }

    /**
     * 获取专辑信息
     * @param albumId
     * @return
     */
    @TsCache(prefix = RedisConstant.ALBUM_INFO_PREFIX)
    @Override
    public AlbumInfo getAlbumInfo(Long albumId) {
        //获取专辑信息
        AlbumInfo albumInfo = this.getById(albumId);
        //获取专辑属性值列表
        if (albumInfo != null) {
            //select * from album_attribute_value where album_id = ? and is_deleted=0;
            List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueMapper.selectList(
                    new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
            //设置专辑属性值列表，AlbumAttributeValueVoList
            albumInfo.setAlbumAttributeValueVoList(albumAttributeValues);
        }
        //返回结果
        return albumInfo;
    }


    /**
     * 删除专辑
     * @param albumId 专辑ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAlbumInfo(Long albumId) {
        //删除专辑，专辑属性表，专辑统计表
        // album_attribute_value\album_info\album_stat
        //update album_info set is_delete=1 where id = ? and is_delete=0;
        //注意不要用自己的service层，出现自调用，事务失效
        albumInfoMapper.deleteById(albumId);
        //update album_attribute_value set is_delete=1 where album_id = ? and is_delete=0; 逻辑删除
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        //update album_stat set is_delete=1 where album_id = ? and is_delete=0;
        albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
    }

    /**
     * 获取当前用户专辑分页信息
     * @param albumInfoPage
     * @param albumInfoQuery
     * @return
     */
    @Override
    public IPage<AlbumListVo> findUserAlbumPage(Page<AlbumListVo> albumInfoPage, AlbumInfoQuery albumInfoQuery) {
        //调用mapper，返回结果
        return albumInfoMapper.selectUserAlbumPage(albumInfoPage,albumInfoQuery);

    }

    /**
     * 保存专辑信息
     * @param albumInfoVo
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo,Long userId) {
        //1、保存专辑信息
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo,albumInfo);
        //指定userID，免费试听集数，免费试听秒数，审核状态
        albumInfo.setUserId(userId);

        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {
            //如果付费，免费试听集数，
            albumInfo.setTracksForFree(5);
        }
        //默认审核状态为审核通过
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        //插入专辑
        albumInfoMapper.insert(albumInfo);
        //2、保存专辑属性值中间表信息
        List<AlbumAttributeValueVo> albumAttributeValueVoList =
                albumInfoVo.getAlbumAttributeValueVoList();
        /*
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)){
            //如果专辑属性值List不为空，插入中间表数据
            ArrayList<AlbumAttributeValue> albumAttributeValueList = new ArrayList<>();
            for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                //获取中间表信息
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                BeanUtils.copyProperties(albumAttributeValueVo,albumAttributeValue);
                //获取专辑id
                albumAttributeValue.setAlbumId(albumInfo.getId());
                //插入中间表数据
                albumAttributeValueMapper.insert(albumAttributeValue);
            }
        }*/

        //2、优化版：批量保存，专辑属性值中间表信息

        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)){
            //如果专辑属性值List不为空，插入中间表数据
            List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
                albumAttributeValue.setAlbumId(albumInfo.getId());
                return albumAttributeValue;
            }).collect(Collectors.toList());
            //插入专辑属性值中间表数据
            albumAttributeValueService.saveBatch(albumAttributeValueList);
        }


        //3、保存隐藏信息，专辑统计表信息，播放量，订阅量，浏览量，评论量
        saveAlbumStat(SystemConstant.ALBUM_STAT_PLAY,albumInfo.getId());
        saveAlbumStat(SystemConstant.ALBUM_STAT_SUBSCRIBE,albumInfo.getId());
        saveAlbumStat(SystemConstant.ALBUM_STAT_BROWSE,albumInfo.getId());
        saveAlbumStat(SystemConstant.ALBUM_STAT_COMMENT,albumInfo.getId());

        //4、保存成功，自动上架专辑-》es
        // 使用mq，给elasticsearch发消息，elasticsearch微服务监听到，进行上架
        if ("1".equals(albumInfo.getIsOpen())){
          rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId());
            //	将新增的商品SKUID存入布隆过滤器
            //	获取布隆过滤器，将新增skuID存入布隆过滤器
            RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
            bloomFilter.add(albumInfo.getId());
        }


    }

    public void saveAlbumStat(String statType,Long albumId) {
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumId);
        albumStat.setStatType(statType);
        albumStat.setStatNum(new Random().nextInt(100000));
        albumStatMapper.insert(albumStat);
    }

}
